package com.maozzi.exception;

import com.google.gson.Gson;
import com.maozzi.common.enums.BizCodeEnum;
import com.maozzi.common.exception.BizException;
import com.maozzi.common.model.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 统一异常处理
 *
 * @author maozi
 */
@ControllerAdvice
@Slf4j
public class BizExceptionHandle {

    private final static Gson GSON = new Gson();

    @ExceptionHandler(BizException.class)
    @ResponseStatus(HttpStatus.OK)
    public String handle(HttpServletRequest request, HttpServletResponse response, BizException e) throws Exception {
        log.error("【全局业务异常捕获】", e);
        return handleResponse(request, response, e, BizCodeEnum.VIEW_SERVER_ERROR.getCode(), e.getMessage());
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.OK)
    public String handle(HttpServletRequest request, HttpServletResponse response, NoHandlerFoundException e) throws Exception {
        log.error("【全局页面404异常捕获】", e);
        BizException exception = new BizException(BizCodeEnum.VIEW_NOT_FOUND);

        return handleResponse(request, response, exception, exception.getCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public String handle(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception {
        log.error("【全局未知异常捕获】", e);
        BizException exception = new BizException(BizCodeEnum.VIEW_SERVER_ERROR);

        return handleResponse(request, response, exception, exception.getCode(), e.getMessage());
    }

    /**
     * 根据是否Ajax 请求返回页面或者json
     *
     * @param request  请求
     * @param response 响应
     * @param e        业务异常
     * @param code     页面显示code
     * @param message  页面显示message
     * @return 返回视图
     * @throws Exception 异常
     */
    private static String handleResponse(HttpServletRequest request, HttpServletResponse response, BizException e, String code, String message) throws Exception {
        // 判断请求类型
        String header = request.getHeader("X-Requested-With");
        boolean isAjax = "XMLHttpRequest".equalsIgnoreCase(header);

        String uri = request.getRequestURI();
        if (isAjax || (Objects.nonNull(uri) && uri.startsWith("/rest/"))) {
            ResultVO<String> resultVO = new ResultVO<>();
            resultVO.setCode(e.getCode());
            resultVO.setMessage(e.getMessage());
            resultVO.setData(message);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(GSON.toJson(resultVO));

            return null;
        } else {
            request.setAttribute("code", code);
            request.setAttribute("message", message);
            return "/error";
        }
    }
}
